using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

using Sumen.Model.Model;

namespace Sumen.Business.Presenter.Actor
{
    public class ProductDetailsPresenter 
    {
        const string codePattern = "[A-Z]{2}[0-9]{5}[A-Z0-9]{1}[A-Z]{2}";

        public int Update(object pObjectValue, object pId)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                var oldProductDetails = objEntities.product_details.FirstOrDefault(p => p.Prods_ID == pId);
                product_details newProductDetails = pObjectValue as product_details;
                oldProductDetails.Prods_PRODUCT_DETAILS_COLOR_ID = newProductDetails.Prods_PRODUCT_DETAILS_COLOR_ID;
                oldProductDetails.Prods_PRODUCT_DETAILS_SIZE_ID = newProductDetails.Prods_PRODUCT_DETAILS_SIZE_ID;
                oldProductDetails.Prods_PRODUCT_ID = newProductDetails.Prods_PRODUCT_ID;
                return objEntities.SaveChanges();
            }
        }

        string GetGUId()
        {
            byte[] ba = new byte[16];
            Random rd = new Random();
            rd.NextBytes(ba);
            Guid g = new Guid(ba);
            return g.ToString();
        }

        public int Add(object pObjectValue)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                product_details productDetails = pObjectValue as product_details;
                productDetails.Prods_ID = GetGUId();
                objEntities.product_details.Add(productDetails);
                return objEntities.SaveChanges();
            }
        }


        public int Delete(object pObjectValue)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                product_details productDetails = pObjectValue as product_details;
                product_details pro =
                    (from p in objEntities.product_details select p).FirstOrDefault(
                        p1 => p1.Prods_ID == productDetails.Prods_ID);
                objEntities.product_details.Remove(pro);
                return objEntities.SaveChanges();
            }
        }

        public ICollection<product_details> GetAll()
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                string show = ClsPublic.SYSTEM_DISPLAY_ACTIVED;
                if (show == "1")
                    return (from p in objEntities.product_details select p).ToList();
                else
                    return
                        (from p in objEntities.product_details where p.product.Prod_Actived == 1 select p).ToList();
            }
        }

        public ICollection<object> GetAllInventory()
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                string showActived = ClsPublic.SYSTEM_DISPLAY_ACTIVED;
                var listProductDetailses = (from p in objEntities.product_details where showActived == "1" ? p.product.Prod_Actived != null : p.product.Prod_Actived == 1 select p).ToList();
                var query1 = objEntities.inventories.ToList();
                var query2 = from p in query1
                             group p by new
                             {
                                 p.Inv_PRODUCT_DETAILS_ID
                             }
                                 into Grouped
                                 select
                                     new inventory()
                                     {
                                         Inv_Quantity = Grouped.Sum(p => p.Inv_Quantity),
                                         Inv_Amount = Grouped.Sum(p => p.Inv_Amount),
                                         Inv_PRODUCT_DETAILS_ID = Grouped.Key.Inv_PRODUCT_DETAILS_ID,

                                         Inv_Sale_Price = Grouped.Max(p => p.Inv_Sale_Price),
                                         Inv_Retails_Price = Grouped.Max(p => p.Inv_Retails_Price),
                                         Inv_Agent_Price = Grouped.Max(p => p.Inv_Agent_Price)
                                     };
                var query = from productDetailse in listProductDetailses
                            join products in objEntities.products on productDetailse.Prods_PRODUCT_ID equals products.Prod_ID into InnersProduct
                            from innersProducts in InnersProduct.DefaultIfEmpty()
                            join p in query2
                            on productDetailse.Prods_ID equals p.Inv_PRODUCT_DETAILS_ID into Inners
                            from od in Inners.DefaultIfEmpty(new inventory() { Inv_Quantity = 0, Inv_Retails_Price = innersProducts.Prod_Retails_Price, Inv_Agent_Price = innersProducts.Prod_Agent_Price, Inv_Sale_Price = innersProducts.Prod_Sale_Price, Inv_Amount = 0 })
                            select new
                            {
                                productDetailse.Prods_ID,
                                productDetailse.product.Prod_Product_ID,
                                productDetailse.product.Prod_Product_Name,
                                productDetailse.product_size.Size_Name,
                                productDetailse.product_color.Color_Name,
                                productDetailse.product.product_type.Prodt_Name,
                                innersProducts.Prod_Inward_Price,
                                od.Inv_Amount,
                                od.Inv_Quantity,
                                od.Inv_Sale_Price,
                                od.Inv_Retails_Price,
                                od.Inv_Agent_Price
                            };

                var list = (from p in query.AsEnumerable() select p).ToList();
                //return query.ToList();
                return new[] { list };
            }

        }

        public ICollection<product_details> GetByProductId(object pProductId)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                long productId = long.Parse(pProductId.ToString());
                var query = (from p in objEntities.product_details where p.Prods_PRODUCT_ID == productId select p).ToList();
                return query;
            }
        }

        public string GetListSizeIdByProductId(long pProductId)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                var query = (from p in objEntities.product_details where p.Prods_PRODUCT_ID == pProductId select new { p.product_size.Size_ID }).Distinct();
                string size = "";
                foreach (var productDetailse in query)
                {
                    size += productDetailse.Size_ID + ",";
                }
                return size.Substring(0, size.Length - 1);
            }
        }

        public string GetListColorIdByProductId(long pProductId)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                var query = (from p in objEntities.product_details where p.Prods_PRODUCT_ID == pProductId select new { p.product_color.Color_ID }).Distinct();
                string size = "";
                foreach (var productDetailse in query)
                {
                    size += productDetailse.Color_ID + ",";
                }
                return size.Substring(0, size.Length - 1);
            }
        }

        public product_details GetById(object pId)
        {
            using (sumenEntities objEntities = new sumenEntities())
            {
                string id = pId + string.Empty;
                objEntities.Configuration.LazyLoadingEnabled = false;
                objEntities.Configuration.ProxyCreationEnabled = false;
                product_details productDetails = objEntities.product_details.FirstOrDefault(p => p.Prods_ID == id);
                if (productDetails != null)
                {
                    objEntities.Entry(productDetails).Reference(p => p.product).Load();
                    objEntities.Entry(productDetails).Reference(p => p.product_color).Load();
                    objEntities.Entry(productDetails).Reference(p => p.product_size).Load();
                }

                return productDetails;
            }
        }

        public bool CheckValidCodeProductDetails(string pCode)
        {
            return Regex.IsMatch(pCode, codePattern);
        }

    }
}
